﻿// -----------------------------------------------------------------------------
// DM 是 .NET 5 平台下开发管理的系统。
// Copyright © 2021 DM, 虫儿飞科技 Co.,Ltd.
//
// 框架名称：Furion
// 框架版本：1.0.0
// -----------------------------------------------------------------------------

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Routing;

using System;
using System.Linq;
using System.Threading.Tasks;

namespace Tool
{
    /// <summary>
    /// Web 全局调用日志记录
    /// </summary>
    public class LogFilterAttribute : IAsyncActionFilter
    {
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            #region 拦截之前

            var logcontent = $"ID:{context.ActionDescriptor.Id}";
            logcontent = logcontent.AppendLine(context.HttpContext.GetVisitInfo());

            //提交的参数
            logcontent = logcontent.AppendLine($"参数 ActionArguments:{context.ActionArguments.ToJson()}");

            if (context.ModelState != null)
            {
                //验证信息
                var verifications = context.ModelState.ToDictionary(x => x.Key, v => v.Value.Errors.Select(o => o.ErrorMessage).ToList());

                logcontent = logcontent.AppendLine($"数据验证失败返回：{verifications.ToJson()}");
            }
            var logFloderName = GetLogFloderName(context.HttpContext, context.RouteData);
            // AppEx.GetLogger(logFloderName: logFloderName, retainedFileCountLimit: 24).Debug(logcontent);

            #endregion 拦截之前

            //执行
            var resultContext = await next();

            #region 拦截之后

            //访问返回
            if (context.Result is JsonResult)
            {
                var jsonresult = context.Result as JsonResult;

                logcontent = logcontent.AppendLine($"访问返回：{jsonresult.Value.ToJson()}");
            }

            AppEx.GetLogger(logFloderName: logFloderName, retainedFileCountLimit: 24).Debug(logcontent);

            #endregion 拦截之后

            // 异常拦截
            if (resultContext.Exception != null)
            {
                //操作或操作筛选器导致异常
                // Exception thrown by action or action filter.
                // 设置为null以处理异常。
                //context.Exception = null;
                AppEx.GetLogger(logFloderName: "LogFilterAttribute", retainedFileCountLimit: 20).Error(resultContext.Exception.ToStringEx());
            }
        }

        private string GetLogFloderName(HttpContext httpcontext, RouteData routeData)
        {
            var logFloderName = "default";

            var area = routeData.Values["area"]?.ToString() ?? "";
            var controller = routeData.Values["controller"]?.ToString() ?? "";
            var action = routeData.Values["action"]?.ToString() ?? "";

            if (!string.IsNullOrWhiteSpace(area))
            {
                logFloderName = area;
            }
            else
            {
                var path1 = $"/{area}/{controller}/{action}".Trim('/');//  /test/test
                var path = httpcontext.Request.Path.ToString(); //path:api/test/test
                if (path.Contains(path1))
                {
                    area = path.RemoveLastStr(path1);
                    if (!string.IsNullOrWhiteSpace(area))
                    {
                        logFloderName = area.Trim("//").Trim('/');
                    }
                }
            }
            if (!string.IsNullOrWhiteSpace(controller))
            {
                logFloderName += $"\\{controller}";
            }
            logFloderName = logFloderName.Trim('\\');

            return logFloderName;
        }
    }
}